import requests
import pandas as pd
import json
from typing import List, Dict, Any
import time

def get_invoice_management_data(
    project_id: str = "1721367056409747456",
    section_id: str = "1792796696849342464",
    payment_type_id: str = "",
    page_size: int = 30,
    output_file: str = "发票管理数据.xlsx"
) -> None:
    """
    获取发票管理数据的爬虫函数
    
    Args:
        project_id: 项目ID
        section_id: 标段ID  
        payment_type_id: 支付类型ID
        page_size: 每页数据量
        output_file: 输出Excel文件名
    """
    
    # 基础URL
    base_url = "https://yggc.cncico.com:1080/api/fundSupervision/supervisionInvoiceManages"
    
    # 请求头
    headers = {
        "Accept": "application/json, text/plain, */*",
        "Accept-Encoding": "gzip, deflate, br, zstd",
        "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6",
        "Authorization": "Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3NTU4MjU3ODksInVzZXJfbmFtZSI6IjE1OTA0ODY0NDI5IiwianRpIjoiZDZlMTA4ZWUtZTg4Mi00ZDU0LWI3MTEtNWEwZDAzZTZmNjY1IiwiY2xpZW50X2lkIjoiZGV2LWdhdGV3YXkiLCJzY29wZSI6WyJhbGwiXX0.LdAxzbCpoyqHYw7SSYonP_wynNzl2J-Cc7Jb7cpKWhUQqRRmRTrkCIgIIEp8rhA4r4wAtLWX3VpuuCTyRMun-zlppEJ-fXpJB7Wl5fZV_79KFbDJQwLpGVek70t7WNqumsLqg10JByH0lkhgb8btOvZnpd-eW-gtJKVpK02HOKB_zuLTdMMjKMtfjLJyhYZUQ4Kkp5ElkTaY2_r-9crnIIMO1L41RMfnimOF4W1fFEjbLiPyl6mrW01tsI0riFACunaVGIhhf7uHIZVAcWtdCMHCMaGl4VY_cfVcf5kwR89PjQGxmOPAImNPDEu37n_df8V4pGoLn1l99du5CMwRDA",
        "Cache-Control": "no-cache",
        "Connection": "keep-alive",
        "Cookie": "fine_remember_login=-1; fine_auth_token=eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJhZG1pbiIsInRlbmFudElkIjoiZGVmYXVsdCIsImlzcyI6ImZhbnJ1YW4iLCJkZXNjcmlwdGlvbiI6ImFkbWluKGFkbWluKSIsImV4cCI6MTc1NTM5NzA0MywiaWF0IjoxNzU1Mzk2NDQzLCJqdGkiOiJJTmtyaHpiS1NvTEZLbnV3R2VQY0pVcFdyNDR0N3BUUjJ4dk1Pb09wcVZsei9rRFgifQ.Bjhox4IRi7BbdrrP1tCRuZuUol57_iVHphafOGKnLlI; sessionID=db18bd76-564f-4d69-84f9-ec4703b187bf",
        "Host": "yggc.cncico.com:1080",
        "Pragma": "no-cache",
        "Referer": "https://yggc.cncico.com:1080/contract/fund-manage/invoice-manage/list",
        "Sec-Fetch-Dest": "empty",
        "Sec-Fetch-Mode": "cors",
        "Sec-Fetch-Site": "same-origin",
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36 Edg/139.0.0.0",
        "sec-ch-ua": '"Not;A=Brand";v="99", "Microsoft Edge";v="139", "Chromium";v="139"',
        "sec-ch-ua-mobile": "?0",
        "sec-ch-ua-platform": '"Windows"'
    }
    
    all_records = []
    page_num = 1
    total_pages = 1
    
    print("开始获取发票管理数据...")
    
    try:
        while True:
            # 构建请求参数
            params = {
                "projectId": project_id,
                "sectionId": section_id,
                "payee": "",
                "contractNumber": "",
                "invoiceNumber": "",
                "paymentTypeId": payment_type_id,
                "paymentContent": "",
                "pageNum": page_num,
                "pageSize": page_size
            }
            
            print(f"正在获取第 {page_num} 页数据...")
            
            # 发送请求
            response = requests.get(base_url, headers=headers, params=params, timeout=30)
            response.raise_for_status()
            
            # 解析响应数据
            data = response.json()
            
            if data.get("code") != "00000":
                print(f"请求失败: {data.get('message', '未知错误')}")
                break
            
            # 获取分页信息
            model = data.get("model", {})
            records = model.get("records", [])
            total_pages = model.get("pages", 1)
            
            if not records:
                print(f"第 {page_num} 页没有数据")
                break
            
            # 添加页码信息到每条记录
            for record in records:
                record["页码"] = page_num
            
            all_records.extend(records)
            print(f"第 {page_num} 页获取到 {len(records)} 条数据")
            
            # 检查是否还有下一页
            if page_num >= total_pages:
                break
                
            page_num += 1
            
            # 添加延迟避免请求过快
            time.sleep(1)
        
        print(f"数据获取完成，共获取 {len(all_records)} 条记录")
        
        if all_records:
            # 保存到Excel文件
            save_to_excel(all_records, output_file)
        else:
            print("没有获取到任何数据")
            
    except requests.exceptions.RequestException as e:
        print(f"网络请求错误: {e}")
    except json.JSONDecodeError as e:
        print(f"JSON解析错误: {e}")
    except Exception as e:
        print(f"发生未知错误: {e}")

def save_to_excel(data: List[Dict[str, Any]], filename: str) -> None:
    """
    将数据保存到Excel文件
    
    Args:
        data: 要保存的数据列表
        filename: 输出文件名
    """
    try:
        # 创建DataFrame
        df = pd.DataFrame(data)
        
        # 重新排列列的顺序，将页码放在最前面
        columns = ["页码"] + [col for col in df.columns if col != "页码"]
        df = df[columns]
        
        # 保存到Excel
        df.to_excel(filename, index=False, engine='openpyxl')
        print(f"数据已成功保存到 {filename}")
        
        # 显示数据统计信息
        print(f"\n数据统计:")
        print(f"总记录数: {len(df)}")
        print(f"总列数: {len(df.columns)}")
        print(f"列名: {', '.join(df.columns)}")
        
        # 显示前几行数据预览
        print(f"\n数据预览 (前3行):")
        print(df.head(3).to_string())
        
    except Exception as e:
        print(f"保存Excel文件时发生错误: {e}")

def main():
    """主函数"""
    print("发票管理数据爬虫程序")
    print("=" * 50)
    
    # 调用爬虫函数
    get_invoice_management_data()
    
    print("\n程序执行完成!")

if __name__ == "__main__":
    main()
